Skip to content

produce userdata for VSCode to consume#40

Merged
Eskibear merged 9 commits intomicrosoft:masterfrom
Eskibear:yanzh_tele
Sep 25, 2017
Merged

produce userdata for VSCode to consume#40
Eskibear merged 9 commits intomicrosoft:masterfrom
Eskibear:yanzh_tele

Conversation

@Eskibear
Copy link
Copy Markdown
Member

In VSCode, use following method to get userdata object.

function fetchUserData() {
    return executeJavaLanguageServerCommand(commands.JAVA_FETCH_USER_DATA);
}

@msftclas
Copy link
Copy Markdown

@Eskibear,
Thanks for your contribution as a Microsoft full-time employee or intern. You do not need to sign a CLA.
Thanks,
Microsoft Pull Request Bot

@Eskibear
Copy link
Copy Markdown
Member Author

Moreover, I need an AI key for VSCode to send user data. @akaroml

public class ProtocolServer {
private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME);

private static final Logger loggerUserdata = Logger.getLogger(Configuration.USERDATA_LOGGER_NAME);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming: userDataLogger to make it consistent and readable


private IDebugAdapter debugAdapter;

/* userdataMap Schema:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use javadoc style comments

for (byte b : hashBytes) {
buf.append(Integer.toHexString((b & 0xFF) + 0x100).substring(1));
}
filenameHash = buf.toString();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move out the hash function to adapterutils


if (!response.success || respondingTime > RESPONSE_MAX_DELAY_MS) {
Map<String, Object> props = new HashMap<>();
props.put("respondingTime", respondingTime);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duration

if (!response.success || respondingTime > RESPONSE_MAX_DELAY_MS) {
Map<String, Object> props = new HashMap<>();
props.put("respondingTime", respondingTime);
props.put("requestCommand", requestCommand);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

command

if (th != null) {
errorEntry.put("message", th.getMessage());
StringWriter sw = new StringWriter();
th.printStackTrace(new PrintWriter(sw));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to close StringWriter PrintWriter


// bp count
if ("setBreakpoints".equals(request.command)) {
String filename = request.arguments.get("source").getAsJsonObject().get("path").getAsString();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

path could be null. need cover this case.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could use JsonUtils.fromJson(request.arguments, SetBreakpointArguments.class) to get SetBreakpointArguments object.


props.put("sessionStartAt", String.valueOf(startAt));
props.put("sessionStopAt", String.valueOf(stopAt));
props.put("commandCount", new Gson().toJson(commandCountMap));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use JsonUtils.toJson() method instead of new Gson().


public class JavaDebuggerServerPlugin implements BundleActivator {
private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME);
private static final Logger loggerUserdata = Logger.getLogger(Configuration.USAGE_DATA_LOGGER_NAME);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename to usageDataLogger

* @return List of user data Object.
*/
public List<Object> fetchAll() {
List<Object> ret = new ArrayList<>();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the result always is parsed to an array on vscode js side, Let fetchAll() return queue.toArray() directly instead of a list.

andxu
andxu previously approved these changes Sep 25, 2017
// bp count
if ("setBreakpoints".equals(request.command)) {
String fileIdentifier = "unknown file";
JsonElement pathElement = request.arguments.get("source").getAsJsonObject().get("path");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

request.arguments.get("source").getAsJsonObject().get("path"); [](start = 38, length = 62)

could it possibly raise NullPointerException?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

source is supposed not to be null in setBreakpoints, shall we still double check it, or just assume it as NotNull?

public void stop() {
usageDataSession.reportStop();
this.terminateSession = true;
usageDataSession.submitUsageData();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not sure, but could it possibly be wrapped in sth like a finally block? namely should we report when exception thrown during the session?

@ansyral
Copy link
Copy Markdown
Contributor

ansyral commented Sep 25, 2017

a little bit confused, so now if I would like to log something, i should manually specify which logger i'm using?


public class Configuration {
public static final String LOGGER_NAME = "java-debug";
public static final String USERDATA_LOGGER_NAME = "java-debug-userdata";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

java-debug-usage


public class Configuration {
public static final String LOGGER_NAME = "java-debug";
public static final String USERDATA_LOGGER_NAME = "java-debug-userdata";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

USAGE_LOGGER_NAME

public class ProtocolServer {
private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME);

private static final Logger loggerUserdata = Logger.getLogger(Configuration.USERDATA_LOGGER_NAME);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

loggerUsage


/* userdataMap Schema:
* command: { timestamp: Request JSON String } */
private Map<String, Map<Long, String>> userdataMap = new HashMap<>();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

userdataMap -> usageData

private Map<String, Map<Long, String>> userdataMap = new HashMap<>();

private void recordRequest(Request message) {
userdataMap.putIfAbsent(message.command, new HashMap<Long, String>());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just save the return value and use it in the next line instead of getting it.


public class JavaDebugDelegateCommandHandler implements IDelegateCommandHandler {

public static String FETCH_USER_DATA = "vscode.java.fetchUserData";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FETCH_USER_DATA -> FETCH_USAGE_DATA
vscode.java.fetchUserData -> vscode.java.fetchUsageData

<command id="vscode.java.startDebugSession"/>
<command id="vscode.java.resolveClasspath"/>
<command id="vscode.java.buildWorkspace"/>
<command id="vscode.java.fetchUserData"/>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fetchUsageData

@Override
public void publish(LogRecord record) {
if (record.getLevel().intValue() >= thresholdLevel.intValue()) {
if (record.getThrown() != null) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean a log record does not contain exception or extra data object at the same time?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in Logger, there's no API accepts throwable and extra data at the same time.

}

public static UsageDataStore getInstance() {
return SingletonHolder.INSTANCE;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have multiple sessions going on at the same time, they will share the same session id, which is not expected.

@Eskibear Eskibear merged commit e87577b into microsoft:master Sep 25, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants